import { useSetState } from "react-use";
import { Upload, Modal } from "antd";
import {
  LoadingOutlined,
  PlusOutlined,
  UploadOutlined,
} from "@ant-design/icons";
import styles from "./index.module.less";
import { useMemo, useState } from "react";
import { clsx, toUrlFromImage } from "../common/utils";
import { UploadListType } from "antd/es/upload/interface";
import { FileModel } from "../common/model";
import { useSystemStore } from "../store/system";
import { request, ResBody } from "../common/request";

export function toFileModel(file: any[]): FileModel[] {
  return file
    .filter((f) => f.status === "done")
    .map((f) => ({
      lastModified: f.lastModified,
      name: f.name,
      percent: f.percent,
      size: f.size,
      status: f.status,
      url: f.url,
      type: f.type,
      uid: f.uid,
    }));
}

export const UpFile: React.FC<{
  value?: FileModel[];
  onChange?: (v: any) => void;
  type: UploadListType;
  label?: string;
  maxCount?: number;
}> = (props) => {
  const { value = [], onChange, type, label = "上传", maxCount = 10 } = props;

  const [state, setState] = useSetState({
    previewType: "image" as "image" | "video",
    previewSrc: "",
    previewTitle: "",
    previewOpen: false,
  });

  const uploadBtn = useMemo(() => {
    if (type === "text") {
      return (
        // <Button
        //   icon={<UploadOutlined />}
        //   className="w-full text-font2"
        //   size="large"
        //   type="dashed"
        // >
        //   {label}
        // </Button>
        <div
          className={clsx(
            "text-font2 text-lg border rounded-md",
            "flex items-center justify-center border-border border-dashed"
          )}
        >
          <UploadOutlined />
          &nbsp;
          {label}
        </div>
      );
    }

    if (type === "picture-card" && value.length < maxCount) {
      return (
        <div className="text-font2 text-lg">
          <UploadOutlined />
          <div>{label}</div>
        </div>
      );
    }
  }, [type, value]);

  return (
    <>
      <Upload
        accept={
          type === "picture-card" ? "image/png, image/jpeg, image/gif" : "*"
        }
        className={clsx(styles.UpFile, {
          [styles.picturecls]: value.length === 0,
        })}
        maxCount={maxCount}
        multiple
        customRequest={({ file, onSuccess, onError }) => {
          const reader = new FileReader();
          let filename = (file as any).name;

          reader.onload = () => {
            const stream = new Blob([reader.result!]);
            request
              .post<any, ResBody>("/api/files/upfile-stream", stream, {
                headers: {
                  "Content-Type": `application/octet-stream`,
                  "Content-Disposition": `attachment; filename="${filename}"`,
                },
              })
              .then((res: any) => {
                if (res.code === 200) {
                  onSuccess?.(res);
                } else {
                  onError?.(res);
                }
              })
              .catch(onError);
          };
          reader.readAsArrayBuffer(file as Blob);
        }}
        listType={type}
        fileList={value as any}
        onPreview={async (file) => {
          // console.log(file)
          if (!file.url && !file.preview) {
            if (file.type?.includes("image")) {
              file.preview = await toUrlFromImage(file.originFileObj as File);
            }
            if (file.type?.includes("video")) {
              //如果是视频，直接用后端返回而url
              file.preview = file.response.result[0].url;
            }
          }

          setState({
            previewSrc: file.url || file.preview,
            previewTitle: file.name,
            previewType: file.type?.includes("video") ? "video" : "image",
            previewOpen: true,
          });
        }}
        onChange={(info) => {
          const newFileList = info.fileList.map((file) => {
            const url = file.response?.url;
            if (url) {
              file.url = url;
            }
            return file;
          });

          onChange?.(newFileList);
        }}
      >
        {uploadBtn}
      </Upload>
      <Modal
        open={state.previewOpen}
        title={state.previewTitle}
        footer={null}
        destroyOnClose
        onCancel={() => setState({ previewOpen: false })}
      >
        {state.previewType === "image" ? (
          <img alt="" className="w-full" src={state.previewSrc} />
        ) : (
          <video className="w-full" src={state.previewSrc} controls></video>
        )}
      </Modal>
    </>
  );
};

export const UpAvatar: React.FC<{
  value?: string | null;
  onChange?: (v: string | null) => void;
}> = ({ value, onChange }) => {
  const system = useSystemStore();
  const [loading, setLoading] = useState(false);

  return (
    <Upload
      listType="picture-circle"
      beforeUpload={(file) => {
        const isJpgOrPng =
          file.type === "image/jpeg" || file.type === "image/png";
        if (!isJpgOrPng) {
          system.message("error", "只能上传 JPG/PNG 文件!");
        }
        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isLt2M) {
          system.message("error", "文件大小不能超过 2MB!");
        }
        return isJpgOrPng && isLt2M;
      }}
      customRequest={({ file, onSuccess, onError }) => {
        const reader = new FileReader();
        reader.onload = async (d) => {
          const stream = new Blob([reader.result!]);
          request
            .post("/api/files/upfile-stream", stream)
            .then(onSuccess)
            .catch(onError);
        };
        reader.readAsArrayBuffer(file as Blob);
      }}
      showUploadList={false}
      onChange={(info) => {
        if (info.file.status === "uploading") {
          setLoading(true);
          return;
        }
        if (info.file.status === "done") {
          const url = info.file.response?.url;
          if (url) {
            setLoading(false);
            onChange?.(url);
          }
        }
      }}
    >
      {value ? (
        <img src={value} alt="avatar" className="rounded-full h-full w-full" />
      ) : (
        <div className="text-font2">
          {loading ? <LoadingOutlined /> : <PlusOutlined />}
          <div style={{ marginTop: 4 }}>上传</div>
        </div>
      )}
    </Upload>
  );
};
